<template>
  <el-dialog
    :title="showTile"
    :visible="isShow"
    @close="onClose"
    @open="onOpen"
  >
    <!-- 新增或编辑的表单 -->
    <el-form
      ref="deptFormRef"
      label-width="120px"
      :model="deptForm"
      :rules="deptFormRules"
    >
      <el-form-item label="部门名称" prop="name">
        <el-input
          style="width: 80%"
          placeholder="1-10个字符"
          v-model="deptForm.name"
        />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <!-- 
            diasbled: 禁用，输入框颜色灰度，鼠标会显示禁用
            readonly: 只读（不能改），输入框颜色正常，鼠标也不会显示禁用
         -->
        <el-input
          style="width: 80%"
          placeholder="1-50个字符"
          v-model="deptForm.code"
        />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select
          style="width: 80%"
          placeholder="请选择"
          v-model="deptForm.manager"
        >
          <!-- 
              value: 给v-model用的，发给后台用的
              label: 展示的文本
           -->
          <el-option
            v-for="item in managerList"
            :key="item.id"
            :value="item.username"
            :label="item.username"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input
          style="width: 80%"
          placeholder="1-300个字符"
          type="textarea"
          :rows="3"
          v-model="deptForm.introduce"
        />
      </el-form-item>
    </el-form>
    <!-- el-dialog有专门放置底部操作栏的 插槽  具名插槽 -->
    <div slot="footer">
      <el-button type="primary" size="small" @click="handleOK">确定</el-button>
      <el-button size="small" @click="onClose">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import {
  getManagerListAPI,
  postDeptAPI,
  getDeptDetailAPI,
  putDeptAPI,
} from "@/api/departments";
export default {
  name: "AddOrEditDept",
  props: {
    // 父传子的布尔值，控制对话框的可见性
    isShow: {
      type: Boolean,
      default: false,
    },
    // 父传子的部门对象（当前正在操作的部门）
    deptData: {
      type: Object,
      required: true,
    },
    // 父传子的部门列表（目的做配合自定义校验函数做校验）
    deptList: {
      type: Array,
      required: true,
    },
  },
  data() {
    // 自定义部门名称校验
    const validateDeptName = (rule, value, callback) => {
      // 如果是编辑状态，部门名字可以和自身一样（这种情况是通过的）
      if (this.isEditing && value === this.deptData.name) {
        return callback();
      }
      // some方法，检测数组中是否存在name属性与value一样的，
      // 如果有，就说明名字重复了
      const isRepeat = this.deptList.some(({ name }) => name === value);
      if (isRepeat) {
        // 重复了
        return callback(new Error(`【${value}】部门已经存在了`));
      }
      // 通过了，不传参数
      callback();
    };
    // 自定义部门编码校验
    const validateDeptCode = (rule, value, callback) => {
      // 如果是编辑状态，部门编码可以和自身一样（这种情况是通过的）
      if (this.isEditing && value === this.deptData.code) {
        return callback();
      }
      // 查重
      const isRepeat = this.deptList.some(({ code }) => code === value);
      if (isRepeat) {
        // 重复了
        return callback(new Error(`【${value}】部门编码已存在了`));
      }
      // 通过了
      callback();
    };

    return {
      // 部门表单对象
      deptForm: {
        code: "", // 编码
        introduce: "", // 介绍
        manager: "", // 负责人
        name: "", // 名称
        pid: "", // 上级部门的id，表示是谁的子部门
      },
      // 部门表单校验规则
      deptFormRules: {
        name: [
          {
            required: true,
            message: "部门名称不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 10,
            message: "部门名称要求1-10个字符",
            trigger: ["blur", "change"],
          },
          {
            validator: validateDeptName,
            trigger: ["blur", "change"],
          },
        ],
        code: [
          {
            required: true,
            message: "部门编码不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 50,
            message: "部门编码要求1-50个字符",
            trigger: ["blur", "change"],
          },
          {
            validator: validateDeptCode,
            trigger: ["blur", "change"],
          },
        ],
        manager: [
          {
            required: true,
            message: "部门负责人不能为空",
            trigger: ["blur", "change"],
          },
        ],
        introduce: [
          {
            required: true,
            message: "部门介绍不能为空",
            trigger: ["blur", "change"],
          },
          {
            min: 1,
            max: 300,
            message: "部门介绍要求1-300个字符",
            trigger: ["blur", "change"],
          },
        ],
      },
      // 负责人列表
      managerList: [],
    };
  },
  computed: {
    // 是否是编辑状态
    // 添加和编辑共用同一个deptForm表单对象
    // 添加状态：没有 id 字段
    // 编辑状态：有 id 字段
    isEditing() {
      return this.deptForm.id !== undefined;
    },
    // 展示的标题
    showTile() {
      return this.isEditing ? "编辑部门" : "新增子部门";
    },
  },
  methods: {
    // 当对话框关闭时
    onClose() {
      // 通知父，关闭弹层
      this.$emit("on-close");
      // 清空表单及校验结果
      this.$refs.deptFormRef.resetFields();
      // 重置表单的 id 为 undefined -> 解决弹层标题不对的问题
      this.deptForm.id = undefined;
    },
    // 获取详情
    async getDeptDetail() {
      console.log(this.deptData.id);
      // 调接口、获取详情
      const resp = await getDeptDetailAPI(this.deptData.id);
      // 给表单赋值，做回显
      this.deptForm = {
        ...this.deptForm,
        ...resp.data,
      };
    },
    // 当对话框打开时
    async onOpen() {
      // 默认情况下，每次打开对话框都会发请求
      // 如果 managerList的长度不为零，说明发过请求了，就提前结束
      if (this.managerList.length) return;
      const { data } = await getManagerListAPI();
      this.managerList = data;
    },
    // 添加或编辑部门
    async handleOK() {
      try {
        // 1、整体校验
        await this.$refs.deptFormRef.validate();
        if (this.isEditing) {
          // 编辑
          // 调接口
          await putDeptAPI(this.deptForm);
          // 给提示
          this.$message.success("编辑部门成功");
        } else {
          // 添加
          this.deptForm.pid = this.deptData.id;
          // 2、通过了、调接口
          await postDeptAPI(this.deptForm);
          // 4、给个提示
          this.$message.success("新增部门成功");
        }
        // 3、关闭弹框
        this.onClose();
        // 5、重新获取一次数据
        this.$emit("on-add-success");
      } catch (e) {
        this.$message.error("请输入正确");
      }
    },
  },
};
</script>

<style></style>
